﻿using AutoMapper;
using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Opc.Ua;
using SHRIS.MIS.Common.Util.Model;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.IService.APIExternal;
using SHRIS.MIS.Model.Param.APIExternal;
using SHRIS.MIS.Service.Device;
using SHRIS.MIS.Service.LinePlantService;
using SHRIS.MIS.Web.Controllers;
using SHRIS.MIS.Web.Filter;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace SHRIS.MIS.Web.Areas.DeviceManage.Controllers
{
    [Area("DeviceManage")]
    public class DeviceDetailController : BaseController
    {
        #region 服务注入
        private readonly IMapper _mapper;
        IDeviceService _deviceService;
        LinePlantService _LinePlantService;
        IDeviceStatusService _deviceStatusService;
        IDeviceStatusInfoRecordService _deviceStatusInfoRecordService;
        IThreedCoordinateService _threedCoordinateService;
        ILaserMarkContentService _laserMarkContentService;
        private IOpcDataSourceService _opcDataSourceService;
        public DeviceDetailController(IMapper mapper, LinePlantService LinePlantService, IDeviceService deviceService, IDeviceStatusService deviceStatusService, IDeviceStatusInfoRecordService deviceStatusInfoRecordService, IThreedCoordinateService threedCoordinateService, ILaserMarkContentService laserMarkContentService, IOpcDataSourceService opcDataSourceService)
        {
            _mapper = mapper;
            _deviceService = deviceService;
            _LinePlantService = LinePlantService;
            _deviceStatusService = deviceStatusService;
            _deviceStatusInfoRecordService = deviceStatusInfoRecordService;
            _threedCoordinateService = threedCoordinateService;
            _laserMarkContentService = laserMarkContentService;
            _opcDataSourceService = opcDataSourceService;
        }
        #endregion

        #region 视图功能
        [AuthorizeFilter("device:preview")]
        public IActionResult DevicePreview()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult CC_01()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult CC_02()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult CC_03()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult HoleDepthMeasure()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult Manipulator()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult ThreedCoordinates()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult LaserMarkContent()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult WashMachine()
        {
            return View();
        }

        [AuthorizeFilter("device:preview")]
        public IActionResult OtherDeviceAlarm()
        {
            return View();
        }

        #endregion

        #region API服务
        /// <summary>
        /// 获取设备基本信息
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetDeviceBaiscInfo(string deviceCode)
        {
            if (deviceCode == "Lathe01")
            {
                var obj = new
                {
                    CncStatus = _LinePlantService._05_CncStatus_1,
                    CncOpMode = _LinePlantService._05_CncOpMode_1,
                    ProgramName = _LinePlantService._05_ProgramName_1,
                    NcuBootTime = _LinePlantService._05_NcuBootTime_1,
                    NcuOperationTime= _LinePlantService._05_NcuOperationTime_1,
                    NcuCycleTime=_LinePlantService._05_NcuCycleTime_1,
                    ActToolName=_LinePlantService._05_ActToolName_1,
                    ActDNumber=_LinePlantService._05_ActDNumber_1,
                    ActToolBasePosX=_LinePlantService._05_ActToolBasePosX_1,
                    ActToolBasePosZ=_LinePlantService._05_ActToolBasePosZ_1,
                    SpindleSetSpeed=_LinePlantService._05_SpindleSetSpeed_1,
                    SpindleActSpeed=_LinePlantService._05_SpindleActSpeed_1,
                    SpindleSetFeedRate=_LinePlantService._05_SpindleSetFeedRate_1,
                    SpindleActFeedRate=_LinePlantService._05_SpindleActFeedRate_1,
                    SpindleSpeedOverRate=_LinePlantService._05_SpindleSpeedOverRate_1,
                    CutSpeedOverRate=_LinePlantService._05_CutSpeedOverRate_1,
                    SpindleLoad=_LinePlantService._05_SpindleLoad_1,
                    FineLathe05ProcessData = _LinePlantService._05_FineLathe05ProcessData_1
                };
                return Json(obj);
            }
            else if (deviceCode == "Lathe02")
            {
                var obj = new
                {
                    CncStatus = _LinePlantService._05_CncStatus_2,
                    CncOpMode = _LinePlantService._05_CncOpMode_2,
                    ProgramName = _LinePlantService._05_ProgramName_2,
                    NcuBootTime = _LinePlantService._05_NcuBootTime_2,
                    NcuOperationTime = _LinePlantService._05_NcuOperationTime_2,
                    NcuCycleTime = _LinePlantService._05_NcuCycleTime_2,
                    ActToolName = _LinePlantService._05_ActToolName_2,
                    ActDNumber = _LinePlantService._05_ActDNumber_2,
                    ActToolBasePosX = _LinePlantService._05_ActToolBasePosX_2,
                    ActToolBasePosZ = _LinePlantService._05_ActToolBasePosZ_2,
                    SpindleSetSpeed = _LinePlantService._05_SpindleSetSpeed_2,
                    SpindleActSpeed = _LinePlantService._05_SpindleActSpeed_2,
                    SpindleSetFeedRate = _LinePlantService._05_SpindleSetFeedRate_2,
                    SpindleActFeedRate = _LinePlantService._05_SpindleActFeedRate_2,
                    SpindleSpeedOverRate = _LinePlantService._05_SpindleSpeedOverRate_2,
                    CutSpeedOverRate = _LinePlantService._05_CutSpeedOverRate_2,
                    SpindleLoad = _LinePlantService._05_SpindleLoad_2,
                    FineLathe05ProcessData = _LinePlantService._05_FineLathe05ProcessData_2
                };
                return Json(obj);
            }
            else if (deviceCode == "Lathe03")
            {
                var obj = new
                {
                    CncStatus = _LinePlantService._05_CncStatus_3,
                    CncOpMode = _LinePlantService._05_CncOpMode_3,
                    ProgramName = _LinePlantService._05_ProgramName_3,
                    NcuBootTime = _LinePlantService._05_NcuBootTime_3,
                    NcuOperationTime = _LinePlantService._05_NcuOperationTime_3,
                    NcuCycleTime = _LinePlantService._05_NcuCycleTime_3,
                    ActToolName = _LinePlantService._05_ActToolName_3,
                    ActDNumber = _LinePlantService._05_ActDNumber_3,
                    ActToolBasePosX = _LinePlantService._05_ActToolBasePosX_3,
                    ActToolBasePosZ = _LinePlantService._05_ActToolBasePosZ_3,
                    SpindleSetSpeed = _LinePlantService._05_SpindleSetSpeed_3,
                    SpindleActSpeed = _LinePlantService._05_SpindleActSpeed_3,
                    SpindleSetFeedRate = _LinePlantService._05_SpindleSetFeedRate_3,
                    SpindleActFeedRate = _LinePlantService._05_SpindleActFeedRate_3,
                    SpindleSpeedOverRate = _LinePlantService._05_SpindleSpeedOverRate_3,
                    CutSpeedOverRate = _LinePlantService._05_CutSpeedOverRate_3,
                    SpindleLoad = _LinePlantService._05_SpindleLoad_3,
                    FineLathe05ProcessData = _LinePlantService._05_FineLathe05ProcessData_3
                };
                return Json(obj);
            }
            else
            {
                return Json(new { });
            }
        }

        /// <summary>
        /// 获取设备历史信息
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <param name="stime">开始时间</param>
        /// <param name="etime">结束时间</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetDeviceHistory(string deviceCode,string stime,string etime)
        {
            List<DeviceStatusEntity> _result = new List<DeviceStatusEntity>();
            string _stime = stime + " 00:00:00.000 +08:00";
            string _etime = etime + " 23:23:59.999 +08:00";
            DateTimeOffset s = DateTimeOffset.Parse(_stime);
            DateTimeOffset e = DateTimeOffset.Parse(_etime);
            // 找出记录起始点最近一条记录
            string sql = "select Top 1 * from tb_deviceStatus where DeviceCode='"+ deviceCode + "'and OccurTime<='" + s + "' order by OccurTime desc";
            string _sql= "select Top 1 * from tb_deviceStatus where DeviceCode='" + deviceCode + "'and OccurTime>='" + e + "' order by OccurTime";
            var beforeLast = await _deviceStatusService.SearchBeforeRecordLast(sql);
            var recordResult = await _deviceStatusService.SearchDeviceStatus(deviceCode,s,e);
            var afterLast=await _deviceStatusService.SearchBeforeRecordLast(_sql);

            foreach (DeviceStatusEntity d in beforeLast)
            {
                _result.Add(d);
            }
            foreach(DeviceStatusEntity d in recordResult)
            {
                _result.Add(d);
            }
            foreach(DeviceStatusEntity d in afterLast)
            {
                _result.Add(d);
            }
            List<DeviceStatusEntity> result = Sort(_result);
            var obj = new
            {
                result= result
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取打标机信息
        /// </summary>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageSize"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetLaserMarkRecord(string stime,string etime,int pageSize=1,int limit = 1)
        {
            Pagination p = new Pagination();
            p.Sort = "OccurTime";
            p.PageIndex = pageSize;
            p.PageSize = limit;
            string _stime = stime + " 00:00:00.000 +08:00";
            string _etime = etime + " 23:59:59.999 +08:00";
            DateTimeOffset s = DateTimeOffset.Parse(_stime);
            DateTimeOffset e = DateTimeOffset.Parse(_etime);
            var result = await _laserMarkContentService.SearchByTime(p, s, e);
            var obj = new
            {
                result = result,
                total = p.TotalCount
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取机器人信息
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetRBData()
        {
            var obj = new
            {
                RestartStatus = _LinePlantService._09_RestartStatus,
                EMO = _LinePlantService._09_EMO,
                Ready = _LinePlantService._09_Ready,
                HasWorkpiece = _LinePlantService._09_HasWorkpiece,
                WorkpieceSource = _LinePlantService._09_WorkpieceSource,
                Grab01 = _LinePlantService._09_Grab01,
                Grab02 = _LinePlantService._09_Grab02,
                Put01 = _LinePlantService._09_Put01,
                Put02 = _LinePlantService._09_Put02,
                Position = _LinePlantService._09_Position,
                MStatus=_LinePlantService._09_MStatus,
                MAlarm1=_LinePlantService._09_MAlarm1,
                MAlarm2=_LinePlantService._09_MAlarm2
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取清洗机的信息
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetWashData()
        {
            var obj = new
            {
                BypassStatus = _LinePlantService._01_BypassStatus,
                EMO = _LinePlantService._01_EMO,
                Ready = _LinePlantService._01_Ready,
                End = _LinePlantService._01_End,
                WorkpieceSource = _LinePlantService._01_WorkpieceSource,
                MCode=_LinePlantService._01_MCode,
                MStatus=_LinePlantService._01_MStatus,
                MAlarm1=_LinePlantService._01_MAlarm1,
                WashTime=_LinePlantService._01_WashTime,
                WashSpeed=_LinePlantService._01_WashSpeed
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取故障填写信息
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <param name="stime">开始时间</param>
        /// <param name="etime">结束时间</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetInfoRecord(string deviceCode,string stime,string etime)
        {
            string _stime = stime + " +08:00";
            string _etime = etime + " +08:00";
            DateTimeOffset s = DateTimeOffset.Parse(_stime);
            DateTimeOffset e = DateTimeOffset.Parse(_etime);
            IEnumerable<DeviceStatusInfoRecordEntity> _result = await _deviceStatusInfoRecordService.SearchDevice(deviceCode, s, e);
            List<DeviceStatusInfoRecordEntity> result= SortRecord(_result);
            var obj = new
            {
                result = result
            };
            return Json(obj);
        }

        /// <summary>
        /// 记录故障信息到数据库
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <param name="stime">开始时间</param>
        /// <param name="etime">结束时间</param>
        /// <param name="Reason_1">一级故障</param>
        /// <param name="Reason_2">二级故障</param>
        /// <param name="Reason_3">三级故障</param>
        /// <param name="Reason_4">四级故障</param>
        /// <param name="Des">详情</param>
        /// <param name="Author">记录人</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> RecordDeviceStatusInfo(string deviceCode,string stime,string etime,string Reason_1,string Reason_2,string Reason_3,string Reason_4,string Des,string Author)
        {
            bool result = false;
            string message = "";
            DeviceStatusInfoRecordEntity record = new DeviceStatusInfoRecordEntity();
            Guid guid = Guid.NewGuid();
            record.Id = guid;
            record.DeviceCode = deviceCode;
            string _stime = stime + " +08:00";
            string _etime = etime + " +08:00";
            DateTimeOffset s = DateTimeOffset.Parse(_stime);
            DateTimeOffset e = DateTimeOffset.Parse(_etime);
            record.startTime = s;
            record.endTime = e;
            record.Reason_1 = Reason_1;
            record.Reason_2 = Reason_2;
            record.Reason_3 = Reason_3;
            record.Reason_4 = Reason_4;
            record.Des = Des;
            record.Author = Author;
            record.RecordTime = DateTimeOffset.Now;
            try
            {
                await _deviceStatusInfoRecordService.SaveDevice(record);
                result = true;
            }
            catch(Exception ex)
            {
                result = false;
                message = ex.Message;
            }
            var obj = new
            {
                result = result,
                message= message
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取设备状态
        /// </summary>
        /// <param name="deviceCode">设备编码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetOpcStatus(string deviceCode)
        {
            IEnumerable<OpcServerStatusDto> status= _LinePlantService.GetOpcServerStatus();
            OpcServerStatusDto result = null;
            // 通过deviceCode，找出serverId
            switch (deviceCode)
            {
                case "Lathe01":
                    {
                        Guid guid = new Guid("03C80C83-2515-4778-A636-CFE3BB36E84E");
                        foreach(OpcServerStatusDto d in status)
                        {
                            if (d.server.Id == guid)
                            {
                                result = d;
                            }
                        }
                        break;
                    }
                case "Lathe02":
                    {
                        Guid guid = new Guid("90657642-93F8-4BD0-A800-EAA2CF336830");
                        foreach (OpcServerStatusDto d in status)
                        {
                            if (d.server.Id == guid)
                            {
                                result = d;
                            }
                        }
                        break;
                    }
                case "Lathe03":
                    {
                        Guid guid = new Guid("E5F31D3A-D0DB-4799-93FB-7EE666F8DD52");
                        foreach (OpcServerStatusDto d in status)
                        {
                            if (d.server.Id == guid)
                            {
                                result = d;
                            }
                        }
                        break;
                    }
            }
            return Json(new { result = result });
        }

        /// <summary>
        /// 获取三坐标测量结果
        /// </summary>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageSize"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetThreedCoordinates(string stime,string etime,int pageSize,int limit)
        {
            Pagination p = new Pagination();
            p.Sort = "OccurTime";
            p.PageIndex = pageSize;
            p.PageSize = limit;
            string _stime = stime + " 00:00:00.000 +08:00";
            string _etime = etime + " 23:59:59.999 +08:00";
            DateTimeOffset s = DateTimeOffset.Parse(_stime);
            DateTimeOffset e = DateTimeOffset.Parse(_etime);

            var result= await _threedCoordinateService.SearchBytime(s, e,p);
            var obj =new
            {
                result= result,
                total=p.TotalCount
            };

            return Json(obj);
        }

        /// <summary>
        /// 获取机床报警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetDeviceAlarm(string deviceCode)
        {
            List<string> dataNames = new List<string>();
            switch (deviceCode)
            {
                case "Lathe01":
                    {
                        dataNames.Add("Lathe01Alarm01");
                        dataNames.Add("Lathe01Alarm02");
                        break;
                    }
                case "Lathe02":
                    {
                        dataNames.Add("Lathe02Alarm01");
                        dataNames.Add("Lathe02Alarm02");
                        break;
                    }
                case "Lathe03":
                    {
                        dataNames.Add("Lathe03Alarm01");
                        dataNames.Add("Lathe03Alarm02");
                        break;
                    }
            }
            List<DeviceAlarm> deviceAlarms = await getDeviceAlarmsByAddress(dataNames);

            var obj = new
            {
                deviceAlarms = deviceAlarms
            };
            return Json(obj);
        }

        /// <summary>
        /// 创建三坐标结果excel
        /// </summary>
        /// <param name="group">公司名称</param>
        /// <param name="currentUser">操作员</param>
        /// <param name="date">日期</param>
        /// <param name="time">时间</param>
        /// <param name="filePath">要保存excel的路径</param>
        /// <param name="recordId">三坐标结果的ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> createThreedCoordinatesExcel(string group, string currentUser,string date,string time ,string filePath, string recordId)
        {
            bool result = true;
            string message = "";

            try
            {
                Guid id = new Guid(recordId);
                IEnumerable<ThreeCoordinatesMeasureRecordEntity> info = await _LinePlantService.SearchById(id);
                ThreeCoordinatesMeasureRecordEntity entity = info.First();

                string mCode = entity.MCode;
                string handlMachine = entity.HandleMachine;
                List<string[]> list = new List<string[]>();
                string[] totalData = entity.Result.Split("/");
                for (int i = 0; i < totalData.Length; i++)
                {
                    /**
                     * 结果数组
                     * 实际   误差  趋势  结果
                     */
                    string[] resultData = new string[4];
                    string[] detailData = totalData[i].Split(":");
                    resultData[0] = detailData[1];
                    resultData[1] = detailData[3];
                    resultData[2] = detailData[2];
                    resultData[3] = "未知";
                    if (detailData[4] == "406")
                    {
                        resultData[3] = "不合格";
                    }
                    if (detailData[4] == "336")
                    {
                        resultData[3] = "合格";
                    }
                    list.Add(resultData);
                }

                /**
                 * 生成excel方法
                 * 从模板excel文件中copy一份到目标目录下
                 * 打开刚创建的excel，往里面填值
                 */

                // 1 创建目标文件
                string filename= DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() +"_"+mCode+ ".xlsx";
                string file = filePath + "\\" + filename;
                System.IO.File.Copy("C:\\Users\\42199\\Desktop\\工作资料\\西北新项目\\整理分析\\待开发功能\\excel模板\\三坐标模板.xlsx", file);

                // 2 写入数据
                if (System.IO.File.Exists(file))
                {
                    XLWorkbook xLWorkbook= new XLWorkbook(file);
                    IXLWorksheet worksheet= xLWorkbook.Worksheets.Worksheet("Sheet1");
                    // 公司
                    worksheet.Cell(2, 2).Value = group;
                    // 操作员
                    worksheet.Cell(3, 2).Value = currentUser;
                    // 日期
                    worksheet.Cell(4, 2).Value = date;
                    // 时间
                    worksheet.Cell(5, 2).Value = time;
                    // 物料码
                    worksheet.Cell(6, 2).Value = mCode;
                    // 加工机床
                    worksheet.Cell(7, 2).Value = handlMachine;

                    // 表格数据
                    int startRow = 10;
                    for(int i = 0; i < list.Count; i++)
                    {
                        worksheet.Cell(startRow, 4).Value = list[i][0];
                        worksheet.Cell(startRow, 5).Value = list[i][1];
                        worksheet.Cell(startRow, 8).Value = list[i][2];
                        worksheet.Cell(startRow, 9).Value = list[i][3];
                        startRow++;
                    }
                    using(MemoryStream stream=new MemoryStream())
                    {
                        xLWorkbook.SaveAs(file);
                    }
                }
            }
            catch (Exception ex)
            {
                result = false;
                message = ex.Message;
            }
            
            var obj = new
            {
                result = result,
                message=message
            };
            return Json(obj);
        }

        /// <summary>
        /// 设置刀具补充
        /// </summary>
        /// <param name="deviceCode"></param>
        /// <param name="toolIndex"></param>
        /// <param name="offX"></param>
        /// <param name="offZ"></param>
        /// <param name="offR"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> setToolEdge(string deviceCode, int toolIndex, double? offX, double? offZ, double? offR)
        {
            bool result = true;
            try
            {
                _LinePlantService.setToolEdge(deviceCode, toolIndex, offX, offZ, offR);
            }
            catch (Exception ex)
            {
                result = false;
            }
            return Json(new { result = result });

        }

        /// <summary>
        /// 获取其它设备报警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult getOtherDeviceAlarm()
        {
            // 机器人
            var manipulator = new
            {
                HasAlarm = _LinePlantService._09_HasAlarm,
                AtAuto = _LinePlantService._09_AtAuto,
                MaunalT1 = _LinePlantService._09_MaunalT1,
                ManualT2 = _LinePlantService._09_ManualT2,
                AtInitPosition = _LinePlantService._09_AtInitPosition
            };

            // 激光打码
            var laserMark = new
            {
                DataPatternError = _LinePlantService._06_DataPatternError,
                InitFailed = _LinePlantService._06_InitFailed,
                MarkFailed = _LinePlantService._06_MarkFailed
            };

            // 清洗机
            var washMachine = new
            {
                HasAlarm=_LinePlantService._01_HasAlarm,
                HasError=_LinePlantService._01_HasError
            };

            // 三坐标测量
            var threeCoordinatesMeasure = new
            {
                LoadFileFailed=_LinePlantService._11_LoadFileFailed
            };

            var obj = new {
                manipulator= manipulator,
                laserMark= laserMark,
                washMachine= washMachine,
                threeCoordinatesMeasure= threeCoordinatesMeasure
            };
            return Json(obj);
        }
        #endregion

        #region 辅助方法

        /// <summary>
        /// 通过数据库的DataName字段，获取报警
        /// </summary>
        /// <param name="dataNames"></param>
        /// <returns></returns>
        private async Task<List<DeviceAlarm>> getDeviceAlarmsByAddress(List<string> dataNames)
        {
            List<string> nodeIds = new List<string>();
            OpcDataSourceEntity opcDataSourceEntity = null;
            try
            {
                for (int i = 0; i < dataNames.Count; i++)
                {
                    var alarmEntity = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName("MainPlcControl", dataNames[i]);
                    if (opcDataSourceEntity == null)
                    {
                        opcDataSourceEntity = alarmEntity.First();
                    }
                    nodeIds.Add(alarmEntity.First().SourceAddress);
                }
                List<DataValue> dataValues = _LinePlantService.ReadValues(opcDataSourceEntity, nodeIds);
                int result1 = 0;
                int result2 = 0;
                if (dataValues != null)
                {
                    if (dataValues[0] != null)
                    {
                        result1 = int.Parse(dataValues[0].Value.ToString());
                    }
                    if (dataValues[1] != null)
                    {
                        result2 = int.Parse(dataValues[1].Value.ToString());
                    }
                }
                List<DeviceAlarm> list1 = analysisAlarmResult(result1, alarmList1);
                List<DeviceAlarm> list2 = analysisAlarmResult(result2, alarmList2);
                return list1.Concat(list2).ToList<DeviceAlarm>();
            }
            catch(Exception ex)
            {
                return null;
            }           
        }

        /// <summary>
        /// 机床报警列表1，对应PLC DB9041.DBD76
        /// </summary>
        private List<string> alarmList1 = new List<string>
        {
            "","700001/急停","700002/滤油器堵塞","700003/空调报警","700004/中心架润滑压力低","700005/液压电机过载","700006/排屑器过载","700007/液压压力低",
            "700008/机床未准备好","700009/主轴风机过载","","700011/刀架锁紧超时","","700013/刀塔不在正确刀位上","700014/编程刀号大于实际刀号","700015/防护门打开",
            "700016/润滑压力低","700017/高压冷却电机过载","","700019/润滑液位低","700020/卡盘内外检测同时亮","700021/卡盘未夹紧主轴启动","700022/卡盘未夹紧启动程序","700023/卡盘夹紧超过时间",
            "700024/卡盘未夹紧时间超","","","700027/换刀时间长","700028/+X限位","700029/-X限位","700030/+Z限位","700031/-Z限位"
        };

        /// <summary>
        /// 机床报警列表2，对应PLC DB9041.DBD80
        /// </summary>
        private List<string> alarmList2 = new List<string>
        {
            "","700033/手持盒生效","","","","","","",
            "","","","700043/吸雾器电机过载","700044/提升泵电机过载","700045/高压冷却系统报警","700046/冲屑电机过载","700047/主轴换挡失败",
            "700048/气密检测异常","700049/刀架故障，请查看刀架驱动报警","700050/刀架外部24V低","700051/刀架电机超速","700052/刀架松开后，锁紧信号不消失","700053/刀架松开后锁紧信号出现","700054/刀架锁紧状态，锁紧信号丢失","700055/刀架锁紧超时",
            "700056/刀架电机过载","700057/操纵箱不在安全位置","700058/主轴高低档位异常检测档位，请勿旋转主轴","700059/机床与机械手通讯异常","","","",""
        };

        /// <summary>
        /// 分析报警信息
        /// </summary>
        /// <param name="result"></param>
        /// <param name="alarmList"></param>
        /// <returns></returns>
        public List<DeviceAlarm> analysisAlarmResult(int result, List<string> alarmList)
        {

            int alarmIndex = 0;
            List<DeviceAlarm> list = new List<DeviceAlarm>();

            byte[] bResult = intToBytes(result);
            for (int i = 0; i < bResult.Length; i++)
            {
                BitArray bitArray = new BitArray(bResult[i]);
                for (int j = 0; j < bitArray.Length; j++)
                {
                    if (bitArray[j])
                    {
                        string[] alarmInfo = alarmList[alarmIndex].Split("/");
                        DeviceAlarm deviceAlarm = new DeviceAlarm();
                        deviceAlarm.alarmID = alarmInfo[0];
                        deviceAlarm.alarmInfo = alarmInfo[1];
                        list.Add(deviceAlarm);
                    }
                    alarmIndex++;
                }
            }
            return list;
        }


        /// <summary>
        /// 将int值转为byte数组，用于机床报警，转为byte数组使用
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public byte[] intToBytes(int value)
        {
            byte[] src = new byte[4];
            src[3] = (byte)((value >> 24) & 0xFF);
            src[2] = (byte)((value >> 16) & 0xFF);
            src[1] = (byte)((value >> 8) & 0xFF);
            src[0] = (byte)(value & 0xFF);
            return src;
        }


        /// <summary>
        /// 将HTTP请求对象转换为便于操作的JSON对象
        /// </summary>
        /// <param name="data">req对象</param>
        /// <returns>JSON对象</returns>
        public IDictionary<string, object> ChangeJsonObject(object data)
        {
            var jsonobj = JsonConvert.SerializeObject(data);
            var result = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonobj);
            return result;
        }

        /// <summary>
        /// 对得到的数据进行排序
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public List<DeviceStatusEntity> Sort(List<DeviceStatusEntity> data)
        {
            if (data.Count == 0)
            {
                return data;
            }
            else
            {
                for (int i = 0; i < data.Count; i++)
                {
                    for (int j = 0; j < data.Count - i - 1; j++)
                    {
                        if (data[j].OccurTime > data[j + 1].OccurTime)
                        {
                            DeviceStatusEntity transfer = data[j];
                            data[j] = data[j + 1];
                            data[j + 1] = transfer;
                        }
                    }
                }
                return data;
            }
        }

        public List<DeviceStatusInfoRecordEntity> SortRecord(IEnumerable<DeviceStatusInfoRecordEntity> data)
        {
            List<DeviceStatusInfoRecordEntity> result = new List<DeviceStatusInfoRecordEntity>();
            if (data.Count() != 0)
            {
                foreach(DeviceStatusInfoRecordEntity d in data)
                {
                    result.Add(d);
                }
                for (int i = 0; i < result.Count; i++)
                {
                    for (int j = 0; j < result.Count - i - 1; j++)
                    {
                        if (result[j].RecordTime > result[j + 1].RecordTime)
                        {
                            DeviceStatusInfoRecordEntity transfer = result[j];
                            result[j] = result[j + 1];
                            result[j + 1] = transfer;
                        }
                    }
                }
            }
            return result;
        }

        //public void CreateExcelNew(string capCode, string cap, string res, Op50Result result50, string result60, string result70)

        //{

        //    LogHelper.WriteLog("开始生成excle");



        //    string fileDir = @"C:\WorkResult\";

        //    string fileName = DateTime.Now.Year.ToString() + " - " + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + ".xlsx";

        //    string tempFilePath = fileDir + "160VResultTemplate.xlsx";

        //    string filePath = fileDir + fileName;



        //    if (File.Exists(filePath))

        //    {

        //        Microsoft.Office.Interop.Excel.Application excle = new Microsoft.Office.Interop.Excel.Application();

        //        excle.DisplayAlerts = false;

        //        Microsoft.Office.Interop.Excel.Workbook workBooks = excle.Workbooks.Add(filePath);



        //        Microsoft.Office.Interop.Excel.Worksheet workSheet = (Worksheet)workBooks.Sheets[1];



        //        workSheet.Activate();

        //        for (int i = 5; i < 1000; i++)

        //        {

        //            Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range)workSheet.Cells[i, 1];

        //            if (range.Value2 == null)

        //            {

        //                Microsoft.Office.Interop.Excel.Range r1 = workSheet.Cells[i, 1];

        //                r1.Value = (i - 4).ToString();



        //                Microsoft.Office.Interop.Excel.Range r2 = workSheet.Cells[i, 2];

        //                r2.Value = capCode;



        //                Microsoft.Office.Interop.Excel.Range r4 = workSheet.Cells[i, 4];

        //                r4.Value = result50.moduleVoltage.ToString();



        //                Microsoft.Office.Interop.Excel.Range r5 = workSheet.Cells[i, 5];

        //                r5.Value = result50.middleVoltage.ToString(); ;



        //                Microsoft.Office.Interop.Excel.Range r6 = workSheet.Cells[i, 6];

        //                r6.Value = cap;



        //                Microsoft.Office.Interop.Excel.Range r7 = workSheet.Cells[i, 7];

        //                r7.Value = res;



        //                Microsoft.Office.Interop.Excel.Range r8 = workSheet.Cells[i, 8];

        //                r8.Value = DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString();



        //                Microsoft.Office.Interop.Excel.Range r9 = workSheet.Cells[i, 9];

        //                r9.Value = result50.midNg;



        //                Microsoft.Office.Interop.Excel.Range r10 = workSheet.Cells[i, 10];

        //                r10.Value = result50.diffNg;



        //                Microsoft.Office.Interop.Excel.Range r11 = workSheet.Cells[i, 11];

        //                r11.Value = result50.singleDiffNgCode;



        //                Microsoft.Office.Interop.Excel.Range r12 = workSheet.Cells[i, 12];

        //                r12.Value = result50.standardNg;



        //                Microsoft.Office.Interop.Excel.Range r13 = workSheet.Cells[i, 13];

        //                r13.Value = result50.singleStandardNgCode;





        //                Microsoft.Office.Interop.Excel.Range r14 = workSheet.Cells[i, 14];

        //                r14.Value = result60;



        //                Microsoft.Office.Interop.Excel.Range r15 = workSheet.Cells[i, 15];

        //                r15.Value = result70;



        //                break;

        //            }



        //        }



        //        workBooks.SaveAs(filePath);

        //        workBooks.Close();



        //    }



        //    else

        //    {

        //        Microsoft.Office.Interop.Excel.Application excle = new Microsoft.Office.Interop.Excel.Application();

        //        excle.DisplayAlerts = false;

        //        Microsoft.Office.Interop.Excel.Workbook workBooks = excle.Workbooks.Add(tempFilePath);



        //        Microsoft.Office.Interop.Excel.Worksheet workSheet = workBooks.Sheets[1];



        //        workSheet.Activate();



        //        Microsoft.Office.Interop.Excel.Range r1 = workSheet.Cells[5, 1];

        //        string rowCount = "1";

        //        r1.Value = rowCount.ToString();



        //        Microsoft.Office.Interop.Excel.Range r2 = workSheet.Cells[5, 2];

        //        r2.Value = capCode;



        //        Microsoft.Office.Interop.Excel.Range r6 = workSheet.Cells[5, 6];

        //        r6.Value = cap;



        //        Microsoft.Office.Interop.Excel.Range r7 = workSheet.Cells[5, 7];

        //        r7.Value = res;



        //        Microsoft.Office.Interop.Excel.Range r8 = workSheet.Cells[5, 8];

        //        r8.Value = DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString();



        //        Microsoft.Office.Interop.Excel.Range r9 = workSheet.Cells[5, 9];

        //        r9.Value = result50.midNg;



        //        Microsoft.Office.Interop.Excel.Range r10 = workSheet.Cells[5, 10];

        //        r10.Value = result50.diffNg;



        //        Microsoft.Office.Interop.Excel.Range r11 = workSheet.Cells[5, 11];

        //        r11.Value = result50.singleDiffNgCode;



        //        Microsoft.Office.Interop.Excel.Range r12 = workSheet.Cells[5, 12];

        //        r12.Value = result50.standardNg;



        //        Microsoft.Office.Interop.Excel.Range r13 = workSheet.Cells[5, 13];

        //        r13.Value = result50.singleStandardNgCode;





        //        Microsoft.Office.Interop.Excel.Range r14 = workSheet.Cells[5, 14];

        //        r14.Value = result60;



        //        Microsoft.Office.Interop.Excel.Range r15 = workSheet.Cells[5, 15];

        //        r15.Value = result70;



        //        workBooks.SaveAs(filePath);

        //        workBooks.Close();

        //    }

        //    LogHelper.WriteLog("Excle 记录完成");

        //}
        #endregion
    }
}
